package com.it.day7;

import com.it.day7.annotation.RunTime;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAccumulator;
import java.util.concurrent.atomic.LongAdder;

/**
 * ClassName: LongAdderCalcDemo
 * Description:
 *
 *  50个线程，每个线程100w点赞，求总点赞
 *
 * @Author: csx
 * @Create: 2025/5/13 - 22:46
 * @version: v1.0
 */
public class LongAdderCalcDemo {
    public static void main(String[] args) throws InterruptedException {
        Class<ClickNumber> clazz = ClickNumber.class;
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            if (method.isAnnotationPresent(RunTime.class)) {
                ClickNumber clickNumber = new ClickNumber();
                CountDownLatch countDownLatch = new CountDownLatch(50);
                long startTime = System.currentTimeMillis();
                for (int i = 0; i < 50; i++) {
                    new Thread(() -> {
                        try {
                            for (int j = 0; j < 100 * 10000; j++) {
                                method.invoke(clickNumber);
                            }
                        } catch (InvocationTargetException e) {
                            throw new RuntimeException(e);
                        } catch (IllegalAccessException e) {
                            throw new RuntimeException(e);
                        } finally {
                            countDownLatch.countDown();
                        }
                    }, String.valueOf(i)).start();
                }
                countDownLatch.await();
                long endTime = System.currentTimeMillis();

                long value = 0;
                if (method.getName().equals("add_Synchronized")){
                    value = clickNumber.number;
                } else if (method.getName().equals("add_AtomicInteger")){
                    value = clickNumber.atomicInteger.longValue();
                } else if (method.getName().equals("add_AtomicLong")){
                    value = clickNumber.atomicLong.longValue();
                } else if (method.getName().equals("add_LongAdder")){
                    value = clickNumber.longAdder.longValue();
                } else if (method.getName().equals("add_LongAccumulator")){
                    value = clickNumber.longAccumulator.longValue();
                }
                System.out.println("----执行时间：" + (endTime - startTime) + " 毫秒" + "\t" + method.getName() + "\t" + value);
            }
        }

    }
}

class ClickNumber{
    int number = 0;
    @RunTime
    public synchronized void add_Synchronized(){
        number++;
    }

    AtomicInteger atomicInteger = new AtomicInteger();
    @RunTime
    public void add_AtomicInteger(){
        atomicInteger.incrementAndGet();
    }

    AtomicLong atomicLong = new AtomicLong();
    @RunTime
    public void add_AtomicLong(){
        atomicLong.incrementAndGet();
    }

    LongAdder longAdder = new LongAdder();
    @RunTime
    public void add_LongAdder(){
        longAdder.increment();
    }

    LongAccumulator longAccumulator = new LongAccumulator((x, y) -> x + y, 0);
    @RunTime
    public void add_LongAccumulator(){
        longAccumulator.accumulate(1L);
    }
}











